package com.rndemo;

import android.app.Application;

import com.facebook.infer.annotation.Assertions;
import com.facebook.react.ReactApplication;

import com.facebook.react.ReactInstanceManager;
import com.facebook.react.ReactInstanceManagerBuilder;
import com.facebook.react.ReactNativeHost;
import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.FallbackJSBundleLoader;
import com.facebook.react.bridge.JSBundleLoader;
import com.facebook.react.bridge.JavaScriptExecutorFactory;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactMarker;
import com.facebook.react.bridge.ReactMarkerConstants;
import com.facebook.react.common.LifecycleState;
import com.facebook.react.shell.MainReactPackage;
import com.facebook.react.uimanager.RNUIImplementationProvider;
import com.facebook.react.uimanager.UIImplementationProvider;
import com.facebook.react.uimanager.ViewManager;
import com.facebook.soloader.SoLoader;
import com.rndemo.Environmental.AppData;
import com.rndemo.db.SQLiteDelegate;
import com.rndemo.rn.MyPackage;
import com.rndemo.rn.view.ReactWebViewManager;
import com.rndemo.utils.UtilFile;
import com.rndemo.utils.UtilSystem;

import java.io.File;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import javax.annotation.Nullable;

public class MainApplication extends Application implements ReactApplication {

    private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
        @Override
        protected ReactInstanceManager createReactInstanceManager() {
            //todo(0.54.3) rn 版本 更新是记得更新这里
            ReactMarker.logMarker(ReactMarkerConstants.BUILD_REACT_INSTANCE_MANAGER_START);
            ReactInstanceManagerBuilder builder = ReactInstanceManager.builder()
                    .setApplication(getApplication())
                    .setJSMainModulePath(getJSMainModuleName())
                    .setUseDeveloperSupport(getUseDeveloperSupport())
                    .setRedBoxHandler(getRedBoxHandler())
                    .setJavaScriptExecutorFactory(getJavaScriptExecutorFactory())
                    .setUIImplementationProvider(getUIImplementationProvider())
                    .setInitialLifecycleState(LifecycleState.BEFORE_CREATE);

            for (ReactPackage reactPackage : getPackages()) {
                builder.addPackage(reactPackage);
            }

            String jsBundleFile = getJSBundleFile();
            if (jsBundleFile != null) {
                builder.setJSBundleFile(jsBundleFile);
                builder.setJSBundleLoader(getJSBundleLoader(jsBundleFile));//todo(0.54.3) 重写就是为了加这个
            } else {
                builder.setBundleAssetName(Assertions.assertNotNull(getBundleAssetName()));
            }
            ReactInstanceManager reactInstanceManager = builder.build();
            ReactMarker.logMarker(ReactMarkerConstants.BUILD_REACT_INSTANCE_MANAGER_END);
            return reactInstanceManager;
        }

        @Override
        protected UIImplementationProvider getUIImplementationProvider() {
            return new RNUIImplementationProvider();
        }

        @Override
        public boolean getUseDeveloperSupport() {
            return BuildConfig.DEBUG;
        }

        @Override
        protected String getJSMainModuleName() {
            return "index";
        }
        @Nullable
        @Override
        protected String getJSBundleFile() {
            if(getUseDeveloperSupport()){
                return super.getJSBundleFile();
            }else{
                //拷贝 assets 目录下的 bundle文件到 data/data/versionName/index.android.bundle
                String path = getFilesDir().getPath()+File.separator+
                        AppData.versionName+File.separator+
                        "index.android.bundle";
                File file = new File(path);
                if(!file.exists()){
                    file.getParentFile().mkdirs();
                    try {
                        InputStream is = getApplicationContext().getAssets().open("index.android.bundle");
                        UtilFile.save(is,file,false);
                        is.close();
                    }catch (Exception e){
                    }
                }
                return path;
            }
        }

        @Nullable
        @Override
        protected JavaScriptExecutorFactory getJavaScriptExecutorFactory() {
            return super.getJavaScriptExecutorFactory();
        }

        private JSBundleLoader getJSBundleLoader(String file){
            List<JSBundleLoader> loaders= new ArrayList<>();
            loaders.add(JSBundleLoader.createFileLoader(file));
            return new FallbackJSBundleLoader(loaders);
        }

        @Override
        protected List<ReactPackage> getPackages() {
            return Arrays.<ReactPackage>asList(
                    new MainReactPackage(){
                        @Override
                        public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
                            List<ViewManager> viewManagers = super.createViewManagers(reactContext);
                            for(int i=viewManagers.size()-1;i>=0;i--){
                                ViewManager vm = viewManagers.get(i);
                                if(vm instanceof com.facebook.react.views.webview.ReactWebViewManager){
                                    viewManagers.remove(vm);
                                }
                            }
                            viewManagers.add(new ReactWebViewManager());
                            return viewManagers;
                        }
                    },
                    new MyPackage()
            );
        }
    };

    @Override
    public ReactNativeHost getReactNativeHost() {
        return mReactNativeHost;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        if(getPackageName().equals(UtilSystem.getProcessName(this))){// 进程判断
            mainProcessOnCreate();
        }else{
            otherProcessOnCreate();
        }
    }

    /**
     * 主进程要自行的东西
     */
    private void mainProcessOnCreate(){
        SoLoader.init(this, /* native exopackage */ false);
        AppData.init(this);
        SQLiteDelegate.init(this);
        //TODO 调用网络拉取 bundler文件
        ReactInstanceManager reactInstanceManager = mReactNativeHost.getReactInstanceManager();
        if (!reactInstanceManager.hasStartedCreatingInitialContext()) {
            reactInstanceManager.createReactContextInBackground();
        }
    }
    /**
     * 其他进程要执行的内容
     */
    private void otherProcessOnCreate(){

    }


}
